package com.hmkj.web.controller.my;

import com.hmkj.common.entity.ResultEntity;
import com.hmkj.common.utils.PriceHelper;
import com.hmkj.common.utils.StringUtils;
import com.hmkj.core.constant.ConfigNID;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.mapper.account.AccountCashMapper;
import com.hmkj.core.model.account.AccountModel;
import com.hmkj.core.model.user.UserModel;
import com.hmkj.core.po.account.Account;
import com.hmkj.core.po.user.User;
import com.hmkj.core.po.userAuth.UserAuth;
import com.hmkj.core.po.userBank.UserBank;
import com.hmkj.core.po.userFreeze.UserFreeze;
import com.hmkj.core.service.account.AccountCashService;
import com.hmkj.core.service.account.AccountService;
import com.hmkj.core.service.user.UserService;
import com.hmkj.core.service.userBank.UserBankService;
import com.hmkj.core.service.userFreeze.UserFreezeService;
import com.hmkj.web.controller.GenericController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ......................我佛慈悲......................
 * ......................_oo0oo_.......................
 * .....................o8888888o......................
 * .....................88" . "88......................
 * .....................(| -_- |)......................
 * .....................0\  =  /0......................
 * ...................___/`---'\___....................
 * ..................' \\|     |// '...................
 * ................/ \\|||  :  |||// \.................
 * .............../ _||||| -卍-|||||- \................
 * ..............|   | \\\  -  /// |   |...............
 * ..............| \_|  ''\---/''  |_/ |...............
 * ..............\  .-\__  '-'  ___/-. /...............
 * ............___'. .'  /--.--\  `. .'___.............
 * .........."" '<  `.___\_<|>_/___.' >' ""............
 * ........| | :  `- \`.;`\ _ /`;.`/ - ` : | |.........
 * ........\  \ `_.   \_ __\ /__ _/   .-` /  /.........
 * ....=====`-.____`.___ \_____/___.-`___.-'=====......
 * ......................`=---='.......................
 * ....................................................
 * .................佛祖开光 ,永无BUG...................
 */
@Api(description = "账户资金相关")
@Slf4j
@RestController
@RequestMapping(GenericController.MEMBER_URL + "/account")
public class AppAccountController extends GenericController<Integer, Account> {
    @Resource
    private UserService userService;
    @Resource
    private UserBankService userBankService;
    @Resource
    private AccountService accountService;
    @Resource
    private UserFreezeService userFreezeService;
    @Resource
    private AccountCashService cashService;
    @Resource
    private AccountCashMapper accountCashMapper;

    @ApiOperation(value = "获取用户账户相关信息", notes = "获取用户账户相关信息")
    @ResponseBody
    @RequestMapping(value = "getAccountInfo", method = RequestMethod.POST)
    public ResultEntity<AccountModel> getAccountInfo() {
        User user = getLoginUser();
        Account account = accountService.selectByUID(user.getId());
        UserAuth userAuth = userAuthService.selectByUID(user.getId());
        List<UserBank> userBankList = userBankService.select(new UserBank(t -> {
            t.setUserId(user.getId());
            t.setStatus(UserBank.STATUS.T2.code);
            t.setDelFlag(UserBank.DELFLAG.NORMAL.code);
        }));
        return ok(m -> {
            m.put("account", account);
            m.put("realNameStatus", null == userAuth ? 0 : userAuth.getAuthStatus());
            m.put("userBankSize", null == userBankList ? 0 : userBankList.size());
        }, "获取用户信息成功");
    }

    @ApiOperation(value = "出入策略余额", notes = "出到策略余额")
    @ResponseBody
    @RequestMapping(value = "/transferAvailable", method = RequestMethod.POST)
    public ResultEntity transferAvailable(
            @ApiParam("出入策略金额") @RequestParam(required = true) BigDecimal amount,
            @ApiParam("出入金额类型：1 转入到钱包余额，2 转入到策略余额") @RequestParam(required = true) Integer type
    ) throws Exception {
        User user = getLoginUser();
        if (null == amount || Integer.parseInt(amount.toString()) <= 0) {
            throw new BussinessException("参数错误,参数不能为空且不能小于0");
        }
        accountService.updateAccount(user.getId(), amount, type);
        return ok("转出成功", ResultEntity.SUCCESS);
    }


    @ApiOperation(value = "入金检测", notes = "入金检测")
    @ResponseBody
    @RequestMapping(value = "/checkRecharge", method = RequestMethod.POST)
    public ResultEntity checkRecharge() throws Exception {
        User user = getLoginUser();
        //实名认证信息
        UserAuth userAuth = checkRealNameStatus(user);
        //查找用户是否绑定过银行卡
        List<UserBank> userBankList = userBankService.select(new UserBank(t -> {
            t.setUserId(user.getId());
            t.setStatus(UserBank.STATUS.T2.code);
        }));
        if (CollectionUtils.isEmpty(userBankList)) {
            throw new BussinessException("请先绑定银行卡");
        }
        //资金余额
        Account account = accountService.selectByUID(user.getId());
        return ok(m -> {
            m.put("moneyAvailable", account.getMoneyAvailable());
            m.put("realName", userAuth.getRealname());
            m.put("idCard", userAuth.getIdcard());
            m.put("bankNo", userBankList.get(0).getBankNo());
            m.put("bankId", userBankList.get(0).getId());
        });
    }

    /**
     * 出金检测
     * 0.查询用户冻结信息，如果出金功能被冻结，则提示用户。
     * 1.查询用户认证信息，如果用户没有实名认证，则提示用户先进行实名认证
     * 2.查询当前用户绑定的银行卡列表，如果为空，则提示用户绑卡
     * 3.查询用户的提现密码是否，设置了，如果没有设置，提示用户设置
     * 4.查询当前登录用户类型，如果为 综合会员则，需要显示其保证金账户
     */
    @ApiOperation(value = "出金检测", notes = "出金检测")
    @ResponseBody
    @RequestMapping(value = "/checkCash", method = RequestMethod.POST)
    public ResultEntity checkCash() throws Exception {
        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        //实名检测
        checkRealNameStatus(user);
        UserFreeze freeze = userFreezeService.selectOne(new UserFreeze(uf -> {
            uf.setUserId(user.getId());
        }));
        //0.查询用户冻结信息，如果出金功能被冻结，则提示用户。
        if (freeze.getFreezeCash() == UserFreeze.FREEZECASH.T2.code) {
            throw new BussinessException("出金功能被冻结，请联系客服");
        }
        //查找用户是否绑定过银行卡
        List<UserBank> userBankList = userBankService.select(new UserBank(t -> {
            t.setUserId(user.getId());
            t.setStatus(UserBank.STATUS.T2.code);
        }));
        if (CollectionUtils.isEmpty(userBankList)) {
            throw new BussinessException("请先绑定银行卡");
        }
        if (StringUtils.isBlank(user.getPayPassword())) {
            throw new BussinessException("您的出金密码还没有设置");
        }
        //提现手续费最小值，提现手续费率,最小提现金额，最大提现金额
        BigDecimal cashFeeMin = redisService.get(ConfigNID.CASH_FEE_MIN, BigDecimal.class);
        BigDecimal cashFeeRatio = redisService.get(ConfigNID.CASH_FEE_RATIO, BigDecimal.class);
        BigDecimal cashMin = redisService.get(ConfigNID.CASH_MIN, BigDecimal.class);
        BigDecimal cashMax = redisService.get(ConfigNID.CASH_MAX, BigDecimal.class);
        Integer cashDalyCount = redisService.get(ConfigNID.CASH_DAILY_COUNT, Integer.class);
        Account account = accountService.selectByUID(user.getId());
        Map<String, Object> data = new HashMap<>();
        data.put("mobile", user.getMobilePhone());
        data.put("useAmount", account.getAvailable());
        data.put("cashFeeMin", cashFeeMin);
        data.put("cashFeeRatio", cashFeeRatio);
        data.put("cashMin", cashMin);
        data.put("cashMax", cashMax);
        data.put("cashDalyCount", cashDalyCount);
        data.put("moneyAvailable", account.getMoneyAvailable());
        data.put("bankNo", userBankList.get(0).getBankNo());
        data.put("bankId", userBankList.get(0).getId());
        return ok(data);
    }


    @ApiOperation(value = "出金操作", notes = "出金操作")
    @ResponseBody
    @RequestMapping(value = "/doCash", method = RequestMethod.POST)
    public ResultEntity doCash(@ApiParam("银行卡id") @RequestParam String bankCardId,
                               @ApiParam("提现金额") @RequestParam BigDecimal money,
                               @ApiParam("出金密码(rsa加密再base64加密)") @RequestParam String cashPasswd) throws Exception {
        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        UserFreeze freeze = userFreezeService.selectOne(new UserFreeze(uf -> {
            uf.setUserId(user.getId());
        }));
        //0.查询用户冻结信息，如果出金功能被冻结，则提示用户。
        if (null == freeze || freeze.getFreezeCash() == UserFreeze.FREEZECASH.T2.code) {
            throw new BussinessException("出金功能被冻结，请联系客服");
        }
        String result = checkParam(bankCardId, money, cashPasswd, user);
        if (result != null) {
            throw new BussinessException(result);
        }
        cashService.createCash(bankCardId, money, user);
        return ok("出金成功等待审核", ResultEntity.SUCCESS);
    }


    private String checkParam(String bankCardId, BigDecimal money, String cashPasswd, User user) {
        String result = null;
        BigDecimal cashMin = redisService.get(ConfigNID.CASH_MIN, BigDecimal.class);
        BigDecimal cashMax = redisService.get(ConfigNID.CASH_MAX, BigDecimal.class);
        Integer cashDalyCount = redisService.get(ConfigNID.CASH_DAILY_COUNT, Integer.class);
        BigDecimal cashDalyAmount = redisService.get(ConfigNID.CASH_DAILY_AMOUNT, BigDecimal.class);
        Account account = accountService.selectByUID(user.getId());
        //校验单日出金次数、单日出金总额
        Integer todayCashCount = accountCashMapper.selectTodayCashCount(user.getId());
        BigDecimal todayCashAmount = accountCashMapper.selectTodayCashAmount(user.getId());
        if (null == todayCashAmount) {
            todayCashAmount = BigDecimal.ZERO;
        }
        if (StringUtils.isBlank(bankCardId)) {
            result = "没有选择出金银行卡";
        } else if (cashMin != null && money.compareTo(cashMin) < 0) {
            result = "出金金额不能小于" + cashMin;
        } else if (cashMax != null && money.compareTo(cashMax) > 0) {
            result = "出金金额不能大于" + cashMax;
        } else if (StringUtils.isBlank(cashPasswd)) {
            result = "出金密码不能为空";
        } else if (null == account) {
            result = "账户异常";
        } else if (money.compareTo(account.getMoneyAvailable()) > 0) {
            result = "出金金额不能大于钱包余额";
        } else if (!user.getPayPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(cashPasswd)))) {
            result = "出金密码错误";
        } else if (todayCashCount > cashDalyCount || todayCashCount + 1 > cashDalyCount) {
            result = "您今日提现次数已达最大次数" + cashDalyCount + "次";
        } else if (todayCashAmount.compareTo(cashDalyAmount) == 1 || todayCashAmount.add(money).compareTo(cashDalyAmount) == 1) {
            result = "您今日提现总额已达最大限制总额" + cashDalyAmount;
        }
        if (PriceHelper.isLessThan(account.getMoneyAvailable(), new BigDecimal("100"))) {
            if (!PriceHelper.isEquals(money, account.getAvailable())) {
                result = "可用余额低于100元，必须一次性全部提现";
            }
        }
        return result;
    }


}
